<html>
<head><meta charset="utf-8"><title>data type for dynamic limited concurrent access · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html">data type for dynamic limited concurrent access</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="214228137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214228137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214228137">(Oct 22 2020 at 18:25)</a>:</h4>
<p>For some playground backend tests, I shell out to docker, which is effectively a global resource. A test I want to add requires that there are no other docker tests running at the same time.</p>
<p>I could accomplish that by having a mutex that all of the tests use, preventing any tests from running concurrently. However, <em>most</em> of the other tests can run in parallel, or at least in limited amounts of parallelism (e.g. 2 or 3 tests in parallel doesn't stress out the test machine).</p>
<p>Is there an appropriate type that I could use that would have a magical API like:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">_lock</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">allow_maximum_others</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span><span class="w"> </span><span class="c1">// Prevents all other tests from starting</span>

<span class="kd">let</span><span class="w"> </span><span class="n">_lock</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">allow_maximum_others</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span><span class="w"> </span><span class="c1">// Blocks if there are already 3 tests running</span>
</code></pre></div>

<p>Am I just describing a condvar...?</p>



<a name="214228363"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214228363" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214228363">(Oct 22 2020 at 18:27)</a>:</h4>
<p>jobserver crate could work, or a semaphore I guess?</p>



<a name="214235819"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214235819" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214235819">(Oct 22 2020 at 19:21)</a>:</h4>
<blockquote>
<p>Am I just describing a condvar...?</p>
</blockquote>
<p>You are describing a classical semaphore <span aria-label="wink" class="emoji emoji-1f609" role="img" title="wink">:wink:</span></p>



<a name="214237466"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214237466" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214237466">(Oct 22 2020 at 19:34)</a>:</h4>
<p>Semaphore was indeed the word that I was looking for instead of condvar (course they are related). </p>
<p>However, the semaphores I’ve used have a fixed number created at initialization. In this case I could probably get away with a semaphore that let me take all the tickets, preventing other acquisitions, but it’s still not quite as general as I’m hypothetically picturing. </p>
<p>For example, I’d want to only allow starting a job if there were less than 3 other jobs and then lower the maximum to 3. Then if another call happened for 2, it could also start, but the max would be lowered to 2.</p>



<a name="214237779"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214237779" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214237779">(Oct 22 2020 at 19:36)</a>:</h4>
<p>I don’t know enough about the job server crate/concept; I thought that just ensured a maximum number of jobs across processes. Is it more dynamic than that?</p>



<a name="214246633"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214246633" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214246633">(Oct 22 2020 at 20:52)</a>:</h4>
<blockquote>
<p>Is it more dynamic than that?</p>
</blockquote>
<p>Don't know but from what I can tell from the documentation it isn't.</p>



<a name="214249223"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214249223" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Diggsey <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214249223">(Oct 22 2020 at 21:16)</a>:</h4>
<p>You'd need a semaphore that allows incrementing by more than 1 at a time, or else two tests which both require multiple jobs could hang. It would be simpler to just use a mutex + condition variable - probably by storing a "max parallelism" and then have each test try to take away X amount of parallelism, and wait on the condvar if unable.</p>



<a name="214251207"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214251207" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214251207">(Oct 22 2020 at 21:35)</a>:</h4>
<p>Yes but not only do you need to make sure the limit is uphold when acquiring the toke but also  while the token is handed out. And then you must make sure to "sanely" decide which new  waiting thread you let enter or you might randomly accidentally run all tests exclusively.</p>



<a name="214251672"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214251672" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214251672">(Oct 22 2020 at 21:41)</a>:</h4>
<p>E.g. ignoring test needing more than one job you could have a test with limits: 1a,2a,2b,3a,3b,3c.</p>
<p>The optimal run would be [3a,3b,3c][2a,2b][1a] but they don't stop at the same time so you might have<br>
[3a,3b,3c][3a,3b][3a,2a][2a,2b][2b][1a] or similar for a optimal run. </p>
<p>But if you are not scheduling well and have a long running 2 you might have something like:<br>
[2a,3a][2a, 3b][2a,  3c][2b, 3c][2b][1a].</p>
<p>Or worse you remember a thread with limit 1 is in the queu and use that limit but don't make sure<br>
to schedule it because you just use <code>condvar.notify_one()</code> without priority queue. Leading to a worst case of: [3a][3b][3c][2a][2b][2c][1a] (EDIT: But that can only happen if you base it on concurrent limits).</p>



<a name="214255776"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214255776" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214255776">(Oct 22 2020 at 22:29)</a>:</h4>
<p>Just to be clear you probably only need:</p>
<ul>
<li>a Semaphore with a given capacity (e.g. 100 per logic CPU core)</li>
<li>a <code>acquire_semaphore(&amp;self, cost: usize) -&gt; SemaphoreToken</code> function</li>
<li>on Drop of SemaphoreToken put capacity back in</li>
<li>make SemaphoreToken internally Arc</li>
<li>if a tests needs 3 jobs with cost [30,20,120]  you just call <code>acquire_semaphore(&amp;self, cost: 170)</code> and clone the token twice for each job</li>
<li>alternatively have a <code>multi_acquire_semaphore(&amp;self, costs: impl IntoIterator&lt;Item=usize&gt;) -&gt; Vec&lt;SemaphoreToken&gt;</code> but that's probably not worth it.</li>
<li>For the question which waiters to wake when new capacity is available the greedy approach likely is good enough, i.e. if after putting back a capacity of 20 there is a total free capacity of 22 look for the waiter with the biggest cost &lt; 22.<ul>
<li>You also can formulate this as a optimization problem, more optimal solutions can make sense  once you have <em>many</em> waiting threads. But you could trace unused capacity and if it's not much it might not be worth it.</li>
</ul>
</li>
</ul>



<a name="214324933"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214324933" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214324933">(Oct 23 2020 at 15:04)</a>:</h4>
<p>I was a bit bored so if you haven't found/implemented  a fitting <code>Semaphore</code> you could start with this <strong>bad</strong> implementation:<br>
<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=2ca064943caab79ac6257670ddb99428">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=2ca064943caab79ac6257670ddb99428</a></p>
<p>Note that while it's <strong>bad</strong> for all kind of performance reasons and not fully tested or documented, it might be a good starting point and it might be "good enough" for your use case in testing <span aria-label="wink" class="emoji emoji-1f609" role="img" title="wink">:wink:</span></p>



<a name="214325084"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214325084" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214325084">(Oct 23 2020 at 15:06)</a>:</h4>
<p>Sadly it won't run in play as one of it's dependencies isn't including in <a href="http://play.rust-lang.org">play.rust-lang.org</a>.</p>



<a name="214325431"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214325431" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214325431">(Oct 23 2020 at 15:08)</a>:</h4>
<p>Just add those dependencies to some of the top 100 crates or add it to the rust cookbook. Problem solved.</p>



<a name="214325916"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214325916" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214325916">(Oct 23 2020 at 15:11)</a>:</h4>
<p>Such a warm fuzzy feeling when this happens:</p>
<div class="codehilite"><pre><span></span><code>[maint cf1fe5b] Update crates available in the playground
 2 files changed, 64 insertions(+), 199 deletions(-)
</code></pre></div>



<a name="214325920"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214325920" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214325920">(Oct 23 2020 at 15:11)</a>:</h4>
<p>As a side note there is a bug in the schedule function. <span aria-label="thinking" class="emoji emoji-1f914" role="img" title="thinking">:thinking:</span>  <br>
I just noticed when posting.</p>



<a name="214326239"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214326239" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214326239">(Oct 23 2020 at 15:14)</a>:</h4>
<p>The API feels a bit different  from what I posited though. I was hoping for more like </p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_guard</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">allow_max_concurrency_of</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="c1">// Nothing else may be running here</span>
<span class="p">}</span><span class="w"></span>

<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_guard</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">allow_max_concurrency_of</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span><span class="w"> </span><span class="c1">// Nothing else may be running here</span>
<span class="w">    </span><span class="c1">// This and a maximum of one other thing may be running here</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="214326545"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214326545" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214326545">(Oct 23 2020 at 15:17)</a>:</h4>
<p>My half-baked thoughts were something like...</p>
<p>a <code>Mutex&lt;{running: usize, max: usize}&gt;</code> + <code>Condvar</code>. Acquire the mutex. if running &lt; <code>min(current_max, argument_max)</code>, then increment running, replace max with the <code>min(...)</code>, store the old max in the guard. else block on the condvar.</p>
<p>the guard drop decrements running and stores <code>max(current_max, saved_max)</code></p>



<a name="214326572"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214326572" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214326572">(Oct 23 2020 at 15:17)</a>:</h4>
<p>But I haven't thought through how those <code>min</code> and <code>max</code> would work with all possible threading paths :-)</p>



<a name="214326580"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214326580" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214326580">(Oct 23 2020 at 15:17)</a>:</h4>
<p>BUG: (It always will schedule the largest waiter next, which means that if the largest waiter doesn't fit it will wait until it fits even if there are smaller fitting waiters, so perf might be even worse then I thought).</p>
<p>I know it's a bit different I first started with a "limit" based impl. but realized that this is unnecessary complex. </p>
<p>E.g. by using a <code>GLOBAL_SEMAPHORE = Semaphore::new(100)</code> you could write it as:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_guard</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">GLOBAL_SEMAPHORE</span><span class="p">.</span><span class="n">acquire_semaphore_token</span><span class="p">(</span><span class="mi">100</span><span class="o">/</span><span class="mi">1</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">     </span><span class="kd">let</span><span class="w"> </span><span class="n">_guard</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">GLOBAL_SEMAPHORE</span><span class="p">.</span><span class="n">acquire_semaphore_token</span><span class="p">(</span><span class="mi">100</span><span class="o">/</span><span class="mi">2</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p>I just used <code>100*num_cpus::get()</code> to make it scale with the number of logic CPU threads.</p>



<a name="214327345"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214327345" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214327345">(Oct 23 2020 at 15:24)</a>:</h4>
<p>The problem with limit is that e.g.:</p>
<ul>
<li>
<p>You have jobs which take so many resources that you can only run two of them, and some other<br>
  jobs of which you can run four in parallel.</p>
</li>
<li>
<p>If one of the limit 2 jobs runs you normally would  only be able to run one additional of the limit 4 jobs at the same time.</p>
</li>
<li>
<p>But you limit your jobs to prevent resource over utilization  so running 1 job limit 2 and 2 limit 4 should be fine.</p>
</li>
<li>
<p>So with a capacity of 100 it's now like saying 1 job requiring 50% of available resources and another two which each require 25% of available resources.</p>
</li>
</ul>
<p>This isn't exactly the same but easier to implement and (in many situations) more use-full.</p>



<a name="214327832"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214327832" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214327832">(Oct 23 2020 at 15:28)</a>:</h4>
<p>It seems less useful because now I have to have a total number of resources (e.g. 100) which doesn't correspond to anything "real". </p>
<blockquote>
<p>But you limit your jobs to prevent resource over utilization so running 1 job limit 2 and 2 limit 4 should be fine.</p>
</blockquote>
<p>I don't agree that these are equivalent. "There can one car in my two car driveway" is not the same as "there can be 50 cars in my 100 car driveway" because I don't have a 100 car driveway <span aria-label="wink" class="emoji emoji-1f609" role="img" title="wink">:wink:</span></p>



<a name="214328159"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214328159" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214328159">(Oct 23 2020 at 15:31)</a>:</h4>
<p>Also to be clear this is just a scratch impl. which might be "good enough" for your use case but it has a lot of problems:</p>
<ul>
<li>not fair, risk of waiter starvation in some situations (fix by adding over time increasing scheduling priority)</li>
<li>far from optimal scheduling (fix in many ways, most complex one would be impl. something like a life version of the unconstraint knapsack problem value=priority(based on how_long it waits) weight=cost)</li>
<li>far from optimal data structures used for keeping waiters (fix depend on other fixes)</li>
<li>each waiting thread allocates a Condvar and Mutex (in the parking::Parker impl.)</li>
<li>...</li>
</ul>



<a name="214328512"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214328512" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214328512">(Oct 23 2020 at 15:33)</a>:</h4>
<blockquote>
<p>because I don't have a 100 car driveway</p>
</blockquote>
<p>Sure but what if 100 represents exactly 1 drive way?</p>



<a name="214328750"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214328750" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214328750">(Oct 23 2020 at 15:36)</a>:</h4>
<p>I still think it ends up backwards; I don't want to manually track how many tests I have (adding one to the total resources each time) or worry about the transformation required to do from some LCM of the values in the test to some global total.</p>



<a name="214330116"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214330116" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214330116">(Oct 23 2020 at 15:48)</a>:</h4>
<p>But your  system has only a limited amount of resources (e.g. 100%) so you would just need to estimate the resources a specific test is allowed to take (in %). And to make it scale with the num of CPU's you could make it full_capacity = 100% per CPU. Then there is no need to track how many tests there are.</p>
<p>Anyway, I orginaly started impl a limit based version which is here: <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=68c0ce925896a9897e67732129745c65">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=68c0ce925896a9897e67732129745c65</a> <strong>WARNING: I never really proof read it as I switched the implementation so it might be full of bugs</strong></p>



<a name="214342310"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/data%20type%20for%20dynamic%20limited%20concurrent%20access/near/214342310" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/data.20type.20for.20dynamic.20limited.20concurrent.20access.html#214342310">(Oct 23 2020 at 17:31)</a>:</h4>
<p>Hope that might help you <span aria-label="smiley" class="emoji emoji-1f603" role="img" title="smiley">:smiley:</span></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>